package com.org.buildcycle2;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.BoundCamera;
import org.anddev.andengine.engine.handler.IUpdateHandler;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.IEntity;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLayer;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader.ITMXTilePropertiesListener;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXProperties;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTile;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTileProperty;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTiledMap;
import org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TMXLoadException;
import org.anddev.andengine.entity.modifier.LoopEntityModifier;
import org.anddev.andengine.entity.modifier.PathModifier;
import org.anddev.andengine.entity.modifier.PathModifier.IPathModifierListener;
import org.anddev.andengine.entity.modifier.PathModifier.Path;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import org.anddev.andengine.util.Debug;
import org.anddev.andengine.util.constants.Constants;

/* Original Code by Nicolas Gramlich, heavily modified by Zach Cabot and Sheel Kumar */

public class Level1 extends BaseGameActivity {
        private static final int CAMERA_WIDTH = 480;
        private static final int CAMERA_HEIGHT = 320;

        private BoundCamera mBoundChaseCamera;

        private BitmapTextureAtlas mBitmapTextureAtlas;
        private TiledTextureRegion mPlayerTextureRegion;
        private TMXTiledMap mTMXTiledMap;
        protected int mGroundCount;


        @Override
        public Engine onLoadEngine() {
              //  Toast.makeText(this, "The tile the player is walking on will be highlighted.", Toast.LENGTH_LONG).show();
                this.mBoundChaseCamera = new BoundCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
                return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mBoundChaseCamera));
        }

        @Override
        public void onLoadResources() {
                this.mBitmapTextureAtlas = new BitmapTextureAtlas(128, 128, TextureOptions.DEFAULT);
                BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
                this.mPlayerTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "player.png", 0, 0, 3, 4); // 72x128

                this.mEngine.getTextureManager().loadTexture(this.mBitmapTextureAtlas);
        }

        @Override
        public Scene onLoadScene() {
                this.mEngine.registerUpdateHandler(new FPSLogger());

                final Scene scene = new Scene();

                try {
                        final TMXLoader tmxLoader = new TMXLoader(this, this.mEngine.getTextureManager(), TextureOptions.BILINEAR_PREMULTIPLYALPHA, new ITMXTilePropertiesListener() {
                                @Override
                                public void onTMXTileWithPropertiesCreated(final TMXTiledMap pTMXTiledMap, final TMXLayer pTMXLayer, final TMXTile pTMXTile, final TMXProperties<TMXTileProperty> pTMXTileProperties) {
                					if(pTMXTileProperties.containsTMXProperty("ground", "true")) {
                						Level1.this.mGroundCount++;
                						// This code almost works
                						//groundTiles.add(pTMXTile);
                                }}}
                        );
                        this.mTMXTiledMap = tmxLoader.loadFromAsset(this, "tmx/level1virgawider.tmx");

                      //  Toast.makeText(this, "Cactus count in this TMXTiledMap: " + this.mCactusCount, Toast.LENGTH_LONG).show();
                } catch (final TMXLoadException tmxle) {
                        Debug.e(tmxle);
                }

                // This code almost works, it detects tile grounds, instead have a script running on platform, same difference really
                /*
                for (TMXTile platform : groundTiles) {
        			final Shape floor = new Rectangle(platform.getTileX(), platform.getTileY(), platform.getTileWidth(), platform.getTileHeight());
        			PhysicsFactory.createBoxBody(this.mPhysicsWorld, floor, BodyType.StaticBody, solidFixtureDef);
        			scene.getBottomLayer().addEntity(floor);
        		}

        		final TMXLayer tmxLayer = this.mTMXTiledMap.getTMXLayers().get(0);
        		scene.getBottomLayer().addEntity(tmxLayer);
        		return tmxLayer;
                */
                
                final TMXLayer tmxLayer = this.mTMXTiledMap.getTMXLayers().get(0);
                scene.attachChild(tmxLayer);

                /* Make the camera not exceed the bounds of the TMXEntity. */
                this.mBoundChaseCamera.setBounds(0, tmxLayer.getWidth(), 0, tmxLayer.getHeight());
                this.mBoundChaseCamera.setBoundsEnabled(true);

                /* Calculate the coordinates for the face, so its centered on the camera. */
                final int centerX = (CAMERA_WIDTH - this.mPlayerTextureRegion.getTileWidth()) / 2;
                final int centerY = (CAMERA_HEIGHT - this.mPlayerTextureRegion.getTileHeight()) / 2;

                /* Create the sprite and add it to the scene. */
                final AnimatedSprite player = new AnimatedSprite(80, 131, this.mPlayerTextureRegion);
                this.mBoundChaseCamera.setChaseEntity(player);

                //final Path path = new Path(5).to(0, 255).to(1400, 255).to(0, 255).to(1400, 255).to(0, 255);
                final Path path = new Path(5).to(80, 131).to(195, 131).to(80, 131).to(195, 131).to(80, 131);
                
                player.registerEntityModifier(new LoopEntityModifier(new PathModifier(30, path, null, new IPathModifierListener() {
                        @Override
                        public void onPathStarted(final PathModifier pPathModifier, final IEntity pEntity) {

                        }

                        @Override
                        public void onPathWaypointStarted(final PathModifier pPathModifier, final IEntity pEntity, final int pWaypointIndex) {
                                switch(pWaypointIndex) {
                                        case 0:
                                                player.animate(new long[]{150, 150, 150}, 4, 6, true);
                                                break;
                                        case 1:
                                                player.animate(new long[]{150, 150, 150}, 9, 11, true);
                                                break;
                                        case 2:
                                                player.animate(new long[]{150, 150, 150}, 4, 6, true);
                                                break;
                                        case 3:
                                                player.animate(new long[]{150, 150, 150}, 9, 11, true);
                                                break;
                                }
                        }

                        @Override
                        public void onPathWaypointFinished(final PathModifier pPathModifier, final IEntity pEntity, final int pWaypointIndex) {

                        }

                        @Override
                        public void onPathFinished(final PathModifier pPathModifier, final IEntity pEntity) {

                        }
                })));

                /* Now we are going to create a rectangle that will  always highlight the tile below the feet of the pEntity. 
                final Rectangle currentTileRectangle = new Rectangle(0, 0, this.mTMXTiledMap.getTileWidth(), this.mTMXTiledMap.getTileHeight());
                currentTileRectangle.setColor(1, 0, 0, 0.25f);
                scene.attachChild(currentTileRectangle);*/

                scene.registerUpdateHandler(new IUpdateHandler() {
                        @Override
                        public void reset() { }

                        @Override
                        public void onUpdate(final float pSecondsElapsed) {
                                /* Get the scene-coordinates of the players feet. */
                                final float[] playerFootCordinates = player.convertLocalToSceneCoordinates(12, 31);

                                /* Get the tile the feet of the player are currently waking on. */
                                final TMXTile tmxTile = tmxLayer.getTMXTileAt(playerFootCordinates[Constants.VERTEX_INDEX_X], playerFootCordinates[Constants.VERTEX_INDEX_Y]);
                                if(tmxTile != null) {
                                        // tmxTile.setTextureRegion(null); <-- Rubber-style removing of tiles =D
                                       // currentTileRectangle.setPosition(tmxTile.getTileX(), tmxTile.getTileY());
                                }
                        }
                });
                scene.attachChild(player);

                return scene;
        }

        @Override
        public void onLoadComplete() {

        }

        // ===========================================================
        // Methods
        // ===========================================================

        // ===========================================================
        // Inner and Anonymous Classes
        // ===========================================================
}

/*package com.org.buildcycle2;

import java.util.ArrayList;

import javax.microedition.khronos.opengles.GL10;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.BoundCamera;
import org.anddev.andengine.engine.camera.hud.controls.AnalogOnScreenControl;
import org.anddev.andengine.engine.camera.hud.controls.AnalogOnScreenControl.IAnalogOnScreenControlListener;
import org.anddev.andengine.engine.camera.hud.controls.BaseOnScreenControl;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLayer;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader.ITMXTilePropertiesListener;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXProperties;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTile;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTileProperty;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTiledMap;
import org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TMXLoadException;
import org.anddev.andengine.entity.primitive.Rectangle;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.shape.Shape;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.extension.physics.box2d.FixedStepPhysicsWorld;
import org.anddev.andengine.extension.physics.box2d.PhysicsConnector;
import org.anddev.andengine.extension.physics.box2d.PhysicsFactory;
import org.anddev.andengine.extension.physics.box2d.PhysicsWorld;
import org.anddev.andengine.opengl.texture.Texture;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import org.anddev.andengine.util.Debug;

import android.hardware.SensorManager;
import android.widget.Toast;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.FixtureDef;


public class PlatformLevelActivity extends BaseGameActivity {
    
	// ===========================================================
	// Constants
	// ===========================================================

	private static final int CAMERA_WIDTH = 720;
	private static final int CAMERA_HEIGHT = 480;

	// ===========================================================
	// Fields
	// ===========================================================

	private BoundCamera mCamera;
	
	private Texture mTexture;
	private TiledTextureRegion mBoxFaceTextureRegion;
	
	private Texture mOnScreenControlTexture;
	private TextureRegion mOnScreenControlBaseTextureRegion;
	private TextureRegion mOnScreenControlKnobTextureRegion;
	
	protected int mSolidCount;
	private TMXTiledMap mTMXTiledMap;
	
	private PhysicsWorld mPhysicsWorld;
	
	// ===========================================================
	// Constructors
	// ===========================================================

	// ===========================================================
	// Getter & Setter
	// ===========================================================

	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================
	
	@Override
	public Engine onLoadEngine() {
		this.mCamera = new BoundCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		return new Engine(new EngineOptions(true, 
											ScreenOrientation.LANDSCAPE, 
											new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), 
											this.mCamera));
	}

	@Override
	public void onLoadResources() {
		// Load Player Textures
		this.mTexture = new Texture(64, 64, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		this.mBoxFaceTextureRegion = TextureRegionFactory.createTiledFromAsset(this.mTexture, this, "gfx/face_box_tiled.png", 0, 0, 2, 1); // 64x32
		
		// Load Control Textures
		this.mOnScreenControlTexture = new Texture(256, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		this.mOnScreenControlBaseTextureRegion = TextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "gfx/onscreen_control_base.png", 0, 0);
		this.mOnScreenControlKnobTextureRegion = TextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "gfx/onscreen_control_knob.png", 128, 0);
		
		this.mEngine.getTextureManager().loadTextures(this.mTexture, this.mOnScreenControlTexture);
	}

	@Override
	public Scene onLoadScene() {
		this.mEngine.registerUpdateHandler(new FPSLogger());

		final Scene scene = new Scene(2);
		
		//Define Physics Rules
		this.mPhysicsWorld = new FixedStepPhysicsWorld(30, new Vector2(0, SensorManager.GRAVITY_EARTH), false, 3, 2);
		final FixtureDef solidFixtureDef = PhysicsFactory.createFixtureDef(0, 0, 1.0f); //floor
		final FixtureDef playerFixtureDef = PhysicsFactory.createFixtureDef(1.0f , 0.5f, 1.0f); //player
		
		//Load TMX Tiled Map
		final TMXLayer tmxLayer = loadTMXMap(scene, solidFixtureDef);
		
		// Make the camera not exceed the bounds of the TMXLayer. 
		this.mCamera.setBounds(0, tmxLayer.getWidth(), 0, tmxLayer.getHeight());
		this.mCamera.setBoundsEnabled(true);
		
		//Create walls around the level to contain the player
		final Shape ground = new Rectangle(0, tmxLayer.getHeight() - 2, tmxLayer.getWidth(), 2);
		final Shape roof = new Rectangle(0, 0, tmxLayer.getWidth(), 2);
		final Shape left = new Rectangle(0, 0, 2, tmxLayer.getHeight());
		final Shape right = new Rectangle(tmxLayer.getWidth() - 2, 0, 2, tmxLayer.getHeight());
		
		PhysicsFactory.createBoxBody(this.mPhysicsWorld, ground, BodyType.StaticBody, solidFixtureDef);
		PhysicsFactory.createBoxBody(this.mPhysicsWorld, roof, BodyType.StaticBody, solidFixtureDef);
		PhysicsFactory.createBoxBody(this.mPhysicsWorld, left, BodyType.StaticBody, solidFixtureDef);
		PhysicsFactory.createBoxBody(this.mPhysicsWorld, right, BodyType.StaticBody, solidFixtureDef);
		
		scene.getBottomLayer().addEntity(ground);
		scene.getBottomLayer().addEntity(roof);
		scene.getBottomLayer().addEntity(left);
		scene.getBottomLayer().addEntity(right);
		
		//Load the player
		final AnimatedSprite player;
		final Body playerBody;
		
		final int playerInitX = (CAMERA_WIDTH - this.mBoxFaceTextureRegion.getWidth()) / 2;
		final int playerInitY = (CAMERA_HEIGHT - this.mBoxFaceTextureRegion.getHeight()) / 2;
		
		player = new AnimatedSprite(playerInitX, playerInitY, this.mBoxFaceTextureRegion);
		
		this.mCamera.setChaseShape(player);
				
		playerBody = PhysicsFactory.createBoxBody(this.mPhysicsWorld, player, BodyType.DynamicBody, playerFixtureDef);

		player.animate(200);
		player.setUpdatePhysics(false);

		scene.getTopLayer().addEntity(player);
		this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(player, playerBody, true, true, false, false));
		
		scene.registerUpdateHandler(this.mPhysicsWorld);
		
		// Add an analogOnScreenControl to move the player
		final AnalogOnScreenControl analogOnScreenControl = new AnalogOnScreenControl(0, CAMERA_HEIGHT - this.mOnScreenControlBaseTextureRegion.getHeight(), this.mCamera, this.mOnScreenControlBaseTextureRegion, this.mOnScreenControlKnobTextureRegion, 0.1f, 200, new IAnalogOnScreenControlListener() {
			@Override
			public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) {
				
				if (pValueX != 0 &&  pValueY != 0){
					Vector2 pTempVector = new Vector2(pValueX * 7, pValueY * 7);
	                playerBody.setLinearVelocity(pTempVector);
				}
			}

			@Override
			public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {
				player.addShapeModifier(new SequenceShapeModifier(new ScaleModifier(0.25f, 1, 1.5f), new ScaleModifier(0.25f, 1.5f, 1)));
			}
		});
		analogOnScreenControl.getControlBase().setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		analogOnScreenControl.getControlBase().setAlpha(0.5f);
		analogOnScreenControl.getControlBase().setScaleCenter(0, 128);
		analogOnScreenControl.getControlBase().setScale(1.25f);
		analogOnScreenControl.getControlKnob().setScale(1.25f);
		analogOnScreenControl.refreshControlKnobPosition();

		scene.setChildScene(analogOnScreenControl);
		
		return scene;
	}

	@Override
	public void onLoadComplete() {
		
	}
	
	
	// ===========================================================
	// Methods
	// ===========================================================
	
	
	 * Loads the TMX map and creates the solid bodies for the platforms
	 * @param scene
	 * @param solidTiles
	 * @return
	 
	private TMXLayer loadTMXMap(final Scene scene,
								final FixtureDef solidFixtureDef) {
		// we'll store all the "solid=true" tiles in an array
		final ArrayList<TMXTile> solidTiles = new ArrayList<TMXTile>();
		
		try {
			final TMXLoader tmxLoader = new TMXLoader(this, this.mEngine.getTextureManager(), TextureOptions.BILINEAR_PREMULTIPLYALPHA, new ITMXTilePropertiesListener() {
				@Override
				public void onTMXTileWithPropertiesCreated(final TMXTiledMap pTMXTiledMap, final TMXLayer pTMXLayer, final TMXTile pTMXTile, final TMXProperties<TMXTileProperty> pTMXTileProperties) {
					 We are going to count the tiles that have the property "solid=true" set. 
					if(pTMXTileProperties.containsTMXProperty("solid", "true")) {
						PlatformLevelActivity.this.mSolidCount++;
						
						solidTiles.add(pTMXTile);
					}
				}
			});
			this.mTMXTiledMap = tmxLoader.loadFromAsset(this, "tmx/sandbox2.tmx");

			Toast.makeText(this, "Solid tiles count: " + this.mSolidCount, Toast.LENGTH_LONG).show();
		} catch (final TMXLoadException tmxle) {
			Debug.e(tmxle);
		}
		
		// create bodies for each tile with property solid=true
		for (TMXTile platform : solidTiles) {
			final Shape floor = new Rectangle(platform.getTileX(), platform.getTileY(), platform.getTileWidth(), platform.getTileHeight());
			PhysicsFactory.createBoxBody(this.mPhysicsWorld, floor, BodyType.StaticBody, solidFixtureDef);
			scene.getBottomLayer().addEntity(floor);
		}

		final TMXLayer tmxLayer = this.mTMXTiledMap.getTMXLayers().get(0);
		scene.getBottomLayer().addEntity(tmxLayer);
		return tmxLayer;
	}
}*/
